//----------------------------------------------------------------------------------------------
//	Filename:	BasicSpacePCS.h
//	Author:		Sandro Spina
//	Date:		12/09/2013
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
#pragma once

#include "Space/Space.h"

//----------------------------------------------------------------------------------------------
namespace Illumina 
{
	namespace Core
	{
		class BasicSpacePCS 
			: public ISpace
		{
			
			public:
				struct PrimitiveEx {
					IPrimitive * primitive;
					bool visible;
					Matrix4x4 local_translation;
					Matrix4x4 local_rotation;
					Matrix4x4 local_scale;
					Vector3 scale_factor;
					Vector3 local_translation_vector;
					Matrix4x4 tr_0;
					Matrix4x4 tr_1;
					Vector3 local_rotation_vector;

					Matrix4x4 local_transform;					
					

					PrimitiveEx(void) { };

					PrimitiveEx(IPrimitive * p_primitive, bool p_visible)
					{
						primitive = p_primitive;
						visible = p_visible;
					};
				};

			protected:
				IPrimitive * m_scene;
				List<IPrimitive *> m_visiblePrimitiveList;
				std::map<std::string, PrimitiveEx> m_obbs;
				std::map<std::string, PrimitiveEx> m_models;
				std::map<std::string, PrimitiveEx> m_grids;
		
			public:							
				BasicSpacePCS(const std::string &p_strName) : ISpace(p_strName) { }
				BasicSpacePCS(void) { }

				bool Initialise(void);
				void Shutdown(void);
				bool Build(void);
				bool Update(void);
				
				bool AddOBB(std::string p_tag, IPrimitive * p_obbPrimitive);			//Adds OBB primitive to Map ... if not already present and set it to visible
				bool AddModel(std::string p_tag, IPrimitive * p_modelPrimitive, Matrix4x4 _translation, Matrix4x4 _rotation, Matrix4x4 _scale, Vector3 _local_rot_vector, Matrix4x4 _localTransform, Matrix4x4 _tr0, Matrix4x4 _tr1, Vector3 _scale_factor, Vector3 _local_translation);		//Adds Model primitive to Map ... if not already present and set it to visible
				bool AddSegmentGrid(std::string p_tag, IPrimitive * p_gridPrimitive);	//Adds Grid primitive (KDTreeSphereMesh) ... if not already present and set it to visible
				bool AddModel(std::string p_tag, IPrimitive * p_modelPrimitive);		//Adds Model primitive to Map ... if not already present and set it to visible
				bool SetVisibleOBB(std::string p_tag, bool p_visible);
				bool SetVisibleGrid(std::string p_tag, bool p_visible);
				bool SetVisibleModel(std::string p_tag, bool p_visibile);
				bool SetVisibleAll(bool p_visibilityFlag);
				bool SetVisibleAllOBBs(bool p_visibilityFlag);
				bool SetVisibleAllModels(bool p_visibilityFlag);
				bool SetVisibleAllGrids(bool p_visibilityFlag);
				bool SetVisiblePCS(bool p_visibilityFlag);
				bool ReplaceAllGridsWithModels();
				bool ReplaceGridWithModel(std::string p_tag);
				void ClearAllGrids();
				void ClearAllOBBs();
				void ClearAllModels();
				bool UpdateWorldTransforms(Transformation p_trans);

				bool Intersects(const Ray &p_ray) const;
				bool Intersects(const Ray &p_ray, IPrimitive *p_pExclude) const;
				bool Intersects(const Ray &p_ray, Intersection &p_intersection) const;
				bool Intersects(const Ray &p_ray, Intersection &p_intersection, IPrimitive *p_pExclude) const;

		};
	} 
}